package com.bigtotoro.shuiyincamera.util;

import android.app.Activity;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.ThumbnailUtils;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import io.microshow.rxffmpeg.RxFFmpegInvoke;

/**
 * Created by xiaobing on 2017/12/20.
 */

public class VideoUtil {

    public static final String VIDEO_DIR = Environment.getExternalStorageDirectory()+"/dakashuiyin/video";
    public static final String VIDEO_TEMP_DIR = VIDEO_DIR+"/temp";
    public static final String VIDEO_OUT_DIR = VIDEO_DIR+"/out";
    public static final String VIDEO_SLIDE_DIR = VIDEO_DIR +"/slice";
    public static final String VIDEO_SLIDE_IMAGE_DIR = VIDEO_DIR +"/slice/image";
    public static final String VIDEO_SLIDE_AUDIO_DIR = VIDEO_DIR +"/slice/audio";

    public static void checkVideoDir(){
        File video_dir = new File(VIDEO_DIR);
        if(!video_dir.exists()){
            video_dir.mkdirs();
        }
        File video_temp_dir = new File(VIDEO_TEMP_DIR);
        if(!video_temp_dir.exists()){
            video_temp_dir.mkdirs();
        }
        File video_slice_dir = new File(VIDEO_SLIDE_DIR);
        if(!video_slice_dir.exists()){
            video_slice_dir.mkdirs();
        }
        File video_slice_image_dir = new File(VIDEO_SLIDE_IMAGE_DIR);
        if(!video_slice_image_dir.exists()){
            video_slice_image_dir.mkdirs();
        }

        File video_out_dir = new File(VIDEO_OUT_DIR);
        if(!video_out_dir.exists()){
            video_out_dir.mkdirs();
        }
    }

    public static void clearVideoCache(){
        File video_temp_dir = new File(VIDEO_TEMP_DIR);

        if(video_temp_dir.exists()){
            deleteDir(video_temp_dir);
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     */
    private static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            if(children!=null){
                //递归删除目录中的子目录下
                for (int i=0; i<children.length; i++) {
                    boolean success = deleteDir(new File(dir, children[i]));
                    if (!success) {
                        return false;
                    }
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }

    public static int getWidth(String path){
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//        if (Build.VERSION.SDK_INT >= 14)
//            retriever.setDataSource(path, new HashMap<String, String>());
//        else
//            retriever.setDataSource(path);
        try {
            FileInputStream inputStream = new FileInputStream(path);
            retriever.setDataSource(inputStream.getFD());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
        int height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
        retriever.release();
        return width;
    }

    public static int getRotation(String path){
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//        if (Build.VERSION.SDK_INT >= 14)
//            retriever.setDataSource(path, new HashMap<String, String>());
//        else
//            retriever.setDataSource(path);

        try {
            FileInputStream inputStream = new FileInputStream(path);
            retriever.setDataSource(inputStream.getFD());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
        int height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
        int rotation = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION));
        retriever.release();
        return rotation;
    }

    public static int getHeight(String path){
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//        if (Build.VERSION.SDK_INT >= 14)
//            retriever.setDataSource(path, new HashMap<String, String>());
//        else
//            retriever.setDataSource(path);

        try {
            FileInputStream inputStream = new FileInputStream(path);
            retriever.setDataSource(inputStream.getFD());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
        int height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
        retriever.release();
        return height;
    }



    public static int getDuration(Activity activity, String path){
        int duration;
        try {
            MediaMetadataRetriever mmr = new MediaMetadataRetriever();
            mmr.setDataSource(path);
            duration = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
            mmr.release();
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        return duration;
    }

    public static String getPathFromVideoThumb(String path){
        Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Video.Thumbnails.MINI_KIND);
        return saveBitmap(VIDEO_SLIDE_IMAGE_DIR, bitmap);
    }
    public static String getPathFromVideoThumb(String path, int kind){
        Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(path, kind);
        return saveBitmap(VIDEO_SLIDE_IMAGE_DIR, bitmap);
    }


    public static VideoItem getVideoItemFromPath(String path, int type){
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//        if (Build.VERSION.SDK_INT >= 14){
//            retriever.setDataSource(path, new HashMap<String, String>());
//        } else {
//            retriever.setDataSource(path);
//        }

        try {
            FileInputStream inputStream = new FileInputStream(path);
            retriever.setDataSource(inputStream.getFD());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
        int height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
        int duration = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
        VideoItem item = new VideoItem();
        item.setPath(path);
        item.setWidth(width);
        item.setHeight(height);
        item.setDuration(duration);
        item.setType(type);

        List<VideoItem.VideoBitmap> images = new ArrayList<>();
        if(duration>6000){
            int timeMs = 0;
            do {
                int leftTime = duration-timeMs;
                Bitmap bitmap = retriever.getFrameAtTime(timeMs * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                String bitmapPath = saveBitmap(VIDEO_TEMP_DIR,bitmap);
                VideoItem.VideoBitmap videoBitmap = new VideoItem.VideoBitmap();
                videoBitmap.setPath(bitmapPath);
                if(leftTime>6000){
                    videoBitmap.setDuration(6000);
                }else{
                    videoBitmap.setDuration(leftTime);
                }
                images.add(videoBitmap);
                timeMs += 6000;
            }while ((duration-timeMs)>0);
            item.setImages(images);
        }else{
            if(type==VideoItem.TYPE_HEAD||type == VideoItem.TYPE_TAIL) {
                String bitmapPath = getPathFromVideoThumb(path);//
                VideoItem.VideoBitmap videoBitmap = new VideoItem.VideoBitmap();
                videoBitmap.setPath(bitmapPath);
                images.add(videoBitmap);
                item.setImages(images);
            }
        }
        item.setImages(images);
        retriever.release();
        return item;
    }
    public static VideoItem getVideoItemFromPath(String path){
        return getVideoItemFromPath(path, 0);
    }

    public static VideoItem createVideoItem(String path){
        VideoItem videoItem = new VideoItem();
        videoItem.setPath(path);
        String mediaInfo = RxFFmpegInvoke.getInstance().getMediaInfo(path);

//        String[] ss = mediaInfo.split(";");
//        for(String s : ss){
//            if(s.startsWith("videostream_codecpar_width")){
//                videoItem.setWidth(Integer.parseInt(s.split("=")[1]));
//            }
//            if(s.startsWith("videostream_codecpar_height")){
//                videoItem.setHeight(Integer.parseInt(s.split("=")[1]));
//            }
//
//            if(s.startsWith("videostream_duration")){
//                videoItem.setDuration((int) (Double.parseDouble(s.split("=")[1])/1000));
//            }
//        }
        if(videoItem.getWidth()==0||videoItem.getHeight()==0||videoItem.getDuration()==0){
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            try {
                FileInputStream inputStream = new FileInputStream(path);
                retriever.setDataSource(inputStream.getFD());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


            int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
            int height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
            int rotation = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION));
            int duration = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION))/1000;
            Log.i("createVideoItem","createVideoItem,width=="+width + ", height = "+height+", ratation " +rotation);
            if(rotation==90||rotation==270){
                videoItem.setWidth(height);
                videoItem.setHeight(width);
            }else{
                videoItem.setWidth(width);
                videoItem.setHeight(height);
            }
            videoItem.setDuration(duration);
        }
        return videoItem;
    }

    public static AudioItem createAutioItem(String path){
        AudioItem audioItem = new AudioItem();
        audioItem.setPath(path);
        String mediaInfo = RxFFmpegInvoke.getInstance().getMediaInfo(path);

        String[] ss = mediaInfo.split(";");
        for(String s : ss){
            if(s.startsWith("audiostream_duration")){
                audioItem.setDuration((int) (Double.parseDouble(s.split("=")[1])));
            }
        }

        return audioItem;
    }

    public static String saveBitmap(String dir, Bitmap bitmap){
        String path = dir+"/"+System.currentTimeMillis()+".jpg";
        File file = new File(path);
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        try {
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return path;
    }



}
